package com.hrh.selectsystem.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hrh.selectsystem.aop.MyJwtInterceptor;
import com.hrh.selectsystem.common.BaseResponse;
import com.hrh.selectsystem.common.ErrorCode;
import com.hrh.selectsystem.common.ResultUtils;
import com.hrh.selectsystem.exception.BusinessException;
import com.hrh.selectsystem.exception.ThrowUtils;
import com.hrh.selectsystem.model.dto.choicerecord.ChoiceRecordAddRequest;
import com.hrh.selectsystem.model.dto.mentor.MentorQueryRequest;
import com.hrh.selectsystem.model.dto.student.StudentLoginRequest;
import com.hrh.selectsystem.model.dto.student.StudentUpdatePasswordRequest;
import com.hrh.selectsystem.model.entity.Mentor;
import com.hrh.selectsystem.model.entity.Student;
import com.hrh.selectsystem.model.vo.choiceRecord.ChoiceRecordQueryMentorVO;
import com.hrh.selectsystem.model.vo.choiceRecord.ChoiceRecordVO;
import com.hrh.selectsystem.model.vo.mentor.MentorByStudentVO;
import com.hrh.selectsystem.model.vo.mentor.MentorVO;
import com.hrh.selectsystem.model.vo.student.LoginStudentVO;
import com.hrh.selectsystem.model.vo.student.StudentByTokenVO;
import com.hrh.selectsystem.model.vo.student.StudentVO;
import com.hrh.selectsystem.service.*;
import com.hrh.selectsystem.utils.JwtTokenUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.hrh.selectsystem.service.impl.StudentServiceImpl.SALT;

/**
 * 学生接口
 *
 * @author hrh
 * 
 */
@RestController
@RequestMapping("/student")
@Api(tags = "学生接口")
@Slf4j
public class StudentController {

    @Resource
    private StudentService studentService;
    @Resource
    private ChoiceRecordService choiceRecordService;
    @Resource
    private MentorService mentorService;
    @Resource
    private MentorApplicationCountService mentorApplicationCountService;
    @Resource
    private MatchResultService matchResultService;

    /**
     * 学生登录
     *
     * @param studentLoginRequest
     * @param request
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "学生登录")
    public BaseResponse<LoginStudentVO> studentLogin(@RequestBody StudentLoginRequest studentLoginRequest, HttpServletRequest request) {
        if (studentLoginRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String studentAccount = studentLoginRequest.getStudentaccount();
        String studentPassword = studentLoginRequest.getStudentpassword();
        //加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + studentPassword).getBytes());
        if (StringUtils.isAnyBlank(studentAccount, studentPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        LoginStudentVO loginStudentVO = studentService.studentLogin(studentAccount, studentPassword, request);
        String userrole = "student";
        //登录成功后，生成jwt令牌
        String token = JwtTokenUtils.getToken(
                loginStudentVO.getId().toString(),
                encryptPassword,
                userrole
        );
        loginStudentVO.setToken(token);
        return ResultUtils.success(loginStudentVO);
    }

    /**
     * 根据token获取学生信息
     * @param request
     * @return
     */
    @GetMapping("/token")
    @ApiOperation(value = "根据token获取学生信息(无role)")
    public BaseResponse<StudentByTokenVO> getTokenStudent(HttpServletRequest request) {
        String token = request.getHeader("token");
        String userId = MyJwtInterceptor.getUserIdFromToken(token);
        Student student = studentService.getById(userId);
        if (student == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
        }
        StudentByTokenVO studentByTokenVO = new StudentByTokenVO();
        BeanUtils.copyProperties(student, studentByTokenVO);
        return ResultUtils.success(studentByTokenVO);
    }

    /**
     * 获取当前登录学生信息
     *
     * @param request
     * @return
     */
    @GetMapping("/get-user")
    @ApiOperation(value = "获取当前登录学生信息")
    public BaseResponse<StudentVO> getStudentById(HttpServletRequest request) {
        Student student = studentService.getLoginStudent(request);
        StudentVO studentVO = studentService.getStudentVO(student);
        return ResultUtils.success(studentVO);
    }

    /**
     * 学生注销（已废弃）
     *
     * @param request
     * @return
     */
    @PostMapping("/logout")
    @ApiOperation(value = "学生注销")
    public BaseResponse<Boolean> studentLogout(HttpServletRequest request) {
        try {
            if (request == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            boolean result = studentService.studentLogout(request);
            return ResultUtils.success(result);
        } catch (Exception e) {
            return ResultUtils.success(false);
        }
    }

    /**
     * 学生修改个人密码
     *
     * @param studentUpdatePasswordRequest
     * @param request
     * @return
     */
    @PostMapping("/update-password")
    @ApiOperation(value = "学生修改个人密码")
    public BaseResponse<Boolean> updateMyStudent(@RequestBody StudentUpdatePasswordRequest studentUpdatePasswordRequest,
                                              HttpServletRequest request) {
        try {
            if (studentUpdatePasswordRequest == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            String oldPassword = studentUpdatePasswordRequest.getOldpassword();
            String encryptOldPassword = DigestUtils.md5DigestAsHex((SALT + oldPassword).getBytes());
            if (!encryptOldPassword.equals(studentService.getById(studentService.getLoginStudent(request).getId()).getStudentpassword())){
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "旧密码错误");
            }
            //新密码长度小于6位，不符合规范
            if (studentUpdatePasswordRequest.getStudentpassword().length() < 6) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "新密码长度小于6位，不符合规范");
            }
            Student loginStudent = studentService.getLoginStudent(request);
            Student student = new Student();
            BeanUtils.copyProperties(studentUpdatePasswordRequest, student);
            student.setId(loginStudent.getId());
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + student.getStudentpassword()).getBytes());
            student.setStudentpassword(encryptPassword);
            boolean result = studentService.updateById(student);
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
            return ResultUtils.success(true);
        } catch (Exception e) {
            return ResultUtils.success(false);
        }
    }

    /**
     * 提交志愿
     * @param choiceRecordAddRequest
     * @param request
     * @return
     */
    @PostMapping("/submit-choices")
    @ApiOperation(value = "学生提交志愿")
    public BaseResponse<Boolean> submitChoices(@RequestBody ChoiceRecordAddRequest choiceRecordAddRequest, HttpServletRequest request) {
        try {
            if (choiceRecordAddRequest == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            Student loginStudent = studentService.getLoginStudent(request);
            Long studentId = loginStudent.getId();
            boolean result = choiceRecordService.submitChoices(choiceRecordAddRequest, studentId);
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
            return ResultUtils.success(true);
        } catch (Exception e) {
            return ResultUtils.success(false);
        }
    }

    /**
     * 学生是否已经提交志愿
     * @param request
     * @return
     */
    @GetMapping("/had-submit-choices")
    @ApiOperation(value = "学生是否已经提交志愿")
    public BaseResponse<Boolean> hasSubmitChoices(HttpServletRequest request) {
        try {
            Student loginStudent = studentService.getLoginStudent(request);
            Long studentId = loginStudent.getId();
            ChoiceRecordVO choiceRecordsByStudentId = choiceRecordService.getChoiceRecordsByStudentId(studentId);
            if (choiceRecordsByStudentId == null) {
                return ResultUtils.success(false);
            }
            return ResultUtils.success(true);
        } catch (Exception e) {
            return ResultUtils.success(false);
        }
    }

    /**
     * 获取学生个人选择记录
     * @param request
     * @return
     */
    @GetMapping("/mentor-choices")
    @ApiOperation(value = "获取学生个人选择记录")
    public ChoiceRecordQueryMentorVO getChoiceRecordsByStudentId(HttpServletRequest request){
        Student loginStudent = studentService.getLoginStudent(request);
        Long studentId = loginStudent.getId();
        return choiceRecordService.getStudentMentorChoices(studentId);
    }

    /**
     * 获取学生已选导师id
     * @param request
     * @return
     */
    @GetMapping("/mentor-id")
    @ApiOperation(value = "获取学生已选导师id(仅返回学生id和三个被选导师id)")
    public BaseResponse<ChoiceRecordVO> getChoiceRecordsMentorId(HttpServletRequest request){
        Student loginStudent = studentService.getLoginStudent(request);
        Long studentId = loginStudent.getId();
        return ResultUtils.success(choiceRecordService.getChoiceRecordsByStudentId(studentId));
    }

    /**
     * 学生分页获取导师列表
     * @param mentorQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page")
    @ApiOperation(value = "学生分页获取导师列表")
    public BaseResponse<Page<MentorByStudentVO>> listMentorByPage(@RequestBody MentorQueryRequest mentorQueryRequest,
                                                                  HttpServletRequest request) {
        long current = mentorQueryRequest.getCurrent();
        long size = mentorQueryRequest.getPageSize();
        Page<Mentor> mentorPage = mentorService.page(new Page<>(current, size),
                mentorService.getQueryWrapper(mentorQueryRequest));
        // 获取所有导师的ID
        List<Long> mentorIds = mentorPage.getRecords().stream()
                .map(Mentor::getId)
                .collect(Collectors.toList());

        // 查询每个导师的申请数
        Map<Long, Integer> applicationCountMap = mentorApplicationCountService.getApplicationCountMap(mentorIds);

        // 将Page<Mentor>转换为Page<MentorByStudentVO>
        List<MentorByStudentVO> mentorByStudentVOS = mentorPage.getRecords().stream()
                .map(mentor -> {
                    MentorByStudentVO vo = new MentorByStudentVO();
                    BeanUtils.copyProperties(mentor, vo);
                    vo.setApplicationCount(applicationCountMap.getOrDefault(mentor.getId(), 0));
                    return vo;
                })
                .collect(Collectors.toList());
        // 返回分页结果
        Page<MentorByStudentVO> resultPage = new Page<>();
        resultPage.setCurrent(mentorPage.getCurrent());
        resultPage.setSize(mentorPage.getSize());
        resultPage.setTotal(mentorPage.getTotal());
        resultPage.setRecords(mentorByStudentVOS);
        return ResultUtils.success(resultPage);
    }

    /**
     * 学生获取导师（接受自己申请的导师）的信息
     * @param request
     * @return
     */
    @GetMapping("/accepted-mentor")
    @ApiOperation(value = "学生获取导师（接受自己申请的导师）的信息")
    public BaseResponse<MentorVO> getAcceptedMentor(HttpServletRequest request) {
        // 获取当前登录的学生
        Student loginStudent = studentService.getLoginStudent(request);
        Long studentId = loginStudent.getId();

        // 获取学生已选择的导师
        MentorVO mentorVO = mentorService.getMentorVO(matchResultService.getAcceptedMentor(studentId));

        return ResultUtils.success(mentorVO);
    }
}
